package main

import (
	"banzhuan/config"
	"banzhuan/exchange"
	"github.com/shopspring/decimal"
	"log"
	"math/rand"
	"strconv"
	"time"
)

func main()  {
	_,_,rate_setting,lever:=config.GetConfig()
	log.Println("makeMoney strat=======================")
	log.Println("当前套利空间利率设置为大于",rate_setting,"进行下单。。。。。。。。。。。。。。。。")
	log.Println("当前下单杠杆为:",lever,"，（每次下单为最小下单的此倍数）。。。。。。。。。。。。。。。。")
		for{
			runOrder(rate_setting,lever)
			log.Println("努力寻找组合makeMoney中。。。。。。。。。。。")
			time.Sleep(2*time.Second)
		}

}



//套利下单
func runOrder(rate_setting float64,lever int)  {

	schedulingIndexArg,price_data:=exchange.GetAsset()


	//log.Println("==========",schedulingIndexArg)
	//log.Println("-----------",price_data)

	for i:=0;i<len(schedulingIndexArg) ;i++  {
		step_1_symbol:=price_data[schedulingIndexArg[i].Step1Index].Symbol
		step_1_symbol_tickDenom:=price_data[schedulingIndexArg[i].Step1Index].TickDenom
		step_1_symbol_lotDenom:=price_data[schedulingIndexArg[i].Step1Index].LotDenom
		step_1_symbol_minlots:=price_data[schedulingIndexArg[i].Step1Index].MinLots

		step_2_symbol:=price_data[schedulingIndexArg[i].Step2Index].Symbol
		step_2_symbol_tickDenom:=price_data[schedulingIndexArg[i].Step2Index].TickDenom
		step_2_symbol_lotDenom:=price_data[schedulingIndexArg[i].Step2Index].LotDenom

		step_3_symbol:=price_data[schedulingIndexArg[i].Step3Index].Symbol
		step_3_symbol_tickDenom:=price_data[schedulingIndexArg[i].Step3Index].TickDenom
		step_3_symbol_lotDenom:=price_data[schedulingIndexArg[i].Step3Index].LotDenom

		if price_data[schedulingIndexArg[i].Step1Index].BaseName==price_data[schedulingIndexArg[i].Step3Index].BaseName {
			//log.Println("==============11111111111")
			//获取当前价格
			step_1_buy_price, step_1_buy, step_1_buy_count := exchange.GetDepth(step_1_symbol, step_1_symbol_tickDenom, "SELL")
			//log.Println("++++++++++",step_1_buy_price,step_1_buy,step_1_buy_count)
			if step_1_buy_price == "error" {
				log.Println("step_1_buy_price error：",step_1_buy_price)
				return
			}

			step_2_sell_price, step_2_sell, _ := exchange.GetDepth(step_2_symbol, step_2_symbol_tickDenom, "BUY")

			if step_2_sell_price == "error" {
				log.Println("step_2_sell_price error：",step_2_sell_price)
				return
			}

			step_3_symbol_sell_price, step_3_symbol_sell, _ := exchange.GetDepth(step_3_symbol, step_3_symbol_tickDenom, "BUY")
			if step_3_symbol_sell_price == "error" {
				log.Println("step_3_symbol_sell_price error：",step_3_symbol_sell_price)
				return
			}
			//log.Println("==============22222222222")
			if step_1_buy_price != "" && step_2_sell_price != "" && step_3_symbol_sell_price != "" {

				//log.Println(step_1_symbol, "step_1_buy_price：", step_1_buy_price)
				//log.Println(step_2_symbol, "step_2_sell_price：", step_2_sell_price)
				//log.Println(step_3_symbol, "step_3_symbol_price：", step_3_symbol_sell_price)

				v1, _ := strconv.ParseFloat(step_1_buy_price, 64)
				v2, _ := strconv.ParseFloat(step_2_sell_price, 64)
				v3, _ := strconv.ParseFloat(step_3_symbol_sell_price, 64)

				v1_0 := decimal.NewFromFloat(v1)
				v2_0 := decimal.NewFromFloat(v2)
				v3_0 := decimal.NewFromFloat(v3)
				v2_add_v3 := v2_0.Mul(v3_0)
				v2_add_v3_sub_v1 := v2_add_v3.Sub(v1_0)

				/*
					checkIndo_0:=v2_add_v3_sub_v1.String()
						checkIndo_1,_ := strconv.ParseFloat(checkIndo_0, 64)
						if checkIndo_1<=0 {
							log.Println("checkIndo_1<0:",checkIndo_1)
							//return
						}else {
							log.Println("checkIndo_1>0:",checkIndo_1)
						}

				*/

				rate := v2_add_v3_sub_v1.Div(v1_0)

				rate_float, _ := strconv.ParseFloat(rate.String(), 64)
				log.Println(step_1_symbol, step_2_symbol, step_3_symbol, "套利空间：", rate_float)
				if rate_float >= rate_setting {
					log.Println("=============================================================")
					log.Println(step_1_symbol, "step_1_buy_price：", step_1_buy_price)
					log.Println(step_2_symbol, "step_2_sell_price：", step_2_sell_price)
					log.Println(step_3_symbol, "step_3_symbol_price：", step_3_symbol_sell_price)
					log.Println("==============================================================")
					switch price_data[schedulingIndexArg[i].Step1Index].CoinName {
					case "BAT","LINK","SNT":
						isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_symbol_minlots*step_1_symbol_lotDenom/10)
						if isTrue == "true" {
							available_0,available_0_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

							available_0_v5:=exchange.GetLiuliuliu(available_0,available_0_denom,step_2_symbol_lotDenom)
							if  available_0_v5!=-1{
								isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol,available_0_v5)
								if isTrue == "true" {
									available_1,available_1_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].CoinName)
									available_1_v5:=exchange.GetLiuliuliu(available_1,available_1_denom,step_3_symbol_lotDenom)
									if available_1_v5!=-1 {
										isTrue := exchange.CreateOrder(step_3_symbol_sell, "SELL", step_3_symbol, available_1_v5)
										if isTrue == "true" {
											log.Println("套利成功1次。。。。。。。")
										}
									}
								}
							}
						}
					case "OMG":
						log.Println("=================OMG Out==========================")
					case "DNA":
						 if step_1_buy_count >step_1_symbol_minlots*20*step_1_symbol_lotDenom{

							int64Rand:=RandInt64(5,20)
							intRand:=int(int64Rand)
							isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_symbol_minlots*intRand*step_1_symbol_lotDenom)
							if isTrue == "true" {
								available_0,available_0_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

								available_0_v5:=exchange.GetLiuliuliu(available_0,available_0_denom,step_2_symbol_lotDenom)
								isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol,available_0_v5)
								if isTrue == "true" {
									available_1,available_1_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].CoinName)
									available_1_v5:=exchange.GetLiuliuliu(available_1,available_1_denom,step_3_symbol_lotDenom)
									isTrue := exchange.CreateOrder(step_3_symbol_sell, "SELL", step_3_symbol, available_1_v5)
									if isTrue == "true" {
										log.Println("套利成功1次。。。。。。。")
									}
								}
							}

						}else {
							isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_buy_count)
							if isTrue == "true" {
								available_0,available_0_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

								available_0_v5:=exchange.GetLiuliuliu(available_0,available_0_denom,step_2_symbol_lotDenom)
								isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol,available_0_v5)
								if isTrue == "true" {
									available_1,available_1_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].CoinName)
									available_1_v5:=exchange.GetLiuliuliu(available_1,available_1_denom,step_3_symbol_lotDenom)
									isTrue := exchange.CreateOrder(step_3_symbol_sell, "SELL", step_3_symbol, available_1_v5)
									if isTrue == "true" {
										log.Println("套利成功1次。。。。。。。")
									}
								}
							}

						}

					default:
						if step_1_buy_count >step_1_symbol_minlots*lever*step_1_symbol_lotDenom {
							isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_symbol_minlots*lever*step_1_symbol_lotDenom)
							if isTrue == "true" {
								available_0,available_0_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

								available_0_v5:=exchange.GetLiuliuliu(available_0,available_0_denom,step_2_symbol_lotDenom)
								isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol,available_0_v5)
								if isTrue == "true" {
									available_1,available_1_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].CoinName)
									available_1_v5:=exchange.GetLiuliuliu(available_1,available_1_denom,step_3_symbol_lotDenom)
									isTrue := exchange.CreateOrder(step_3_symbol_sell, "SELL", step_3_symbol, available_1_v5)
									if isTrue == "true" {
										log.Println("套利成功1次。。。。。。。")
									}
								}
							}
						}else {
							isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_buy_count)
							if isTrue == "true" {
								available_0,available_0_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

								available_0_v5:=exchange.GetLiuliuliu(available_0,available_0_denom,step_2_symbol_lotDenom)
								isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol,available_0_v5)
								if isTrue == "true" {
									available_1,available_1_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].CoinName)
									available_1_v5:=exchange.GetLiuliuliu(available_1,available_1_denom,step_3_symbol_lotDenom)
									isTrue := exchange.CreateOrder(step_3_symbol_sell, "SELL", step_3_symbol, available_1_v5)
									if isTrue == "true" {
										log.Println("套利成功1次。。。。。。。")
									}
								}
							}
						}
					}
				}

			}

		}else {
			//log.Println("==============222222222")
			//获取当前价格
			step_1_buy_price, step_1_buy, _ := exchange.GetDepth(step_1_symbol, step_1_symbol_tickDenom, "SELL")

			if step_1_buy_price == "error" {
				return
			}

			step_2_sell_price, step_2_sell, _ := exchange.GetDepth(step_2_symbol, step_2_symbol_tickDenom, "BUY")

			if step_2_sell_price == "error" {
				return
			}

			step_3_symbol_sell_price, step_3_symbol_sell, _ := exchange.GetDepth(step_3_symbol, step_3_symbol_tickDenom, "SELL")
			if step_3_symbol_sell_price == "error" {
				return
			}

			if step_1_buy_price != "" && step_2_sell_price != "" && step_3_symbol_sell_price != "" {

				//log.Println(step_1_symbol, "step_1_buy_price：", step_1_buy_price)
				//log.Println(step_2_symbol, "step_2_sell_price：", step_2_sell_price)
				//log.Println(step_3_symbol, "step_3_symbol_price：", step_3_symbol_sell_price)

				v1, _ := strconv.ParseFloat(step_1_buy_price, 64)
				v2, _ := strconv.ParseFloat(step_2_sell_price, 64)
				v3, _ := strconv.ParseFloat(step_3_symbol_sell_price, 64)

				v1_0 := decimal.NewFromFloat(v1)
				v2_0 := decimal.NewFromFloat(v2)
				v3_0 := decimal.NewFromFloat(v3)
				v2_add_v3 := v2_0.Mul(v3_0)
				v2_add_v3_sub_v1 := v2_add_v3.Sub(v1_0)

				/*
					checkIndo_0:=v2_add_v3_sub_v1.String()
						checkIndo_1,_ := strconv.ParseFloat(checkIndo_0, 64)
						if checkIndo_1<=0 {
							log.Println("checkIndo_1<0:",checkIndo_1)
							//return
						}else {
							log.Println("checkIndo_1>0:",checkIndo_1)
						}

				*/

				rate := v2_add_v3_sub_v1.Div(v1_0)

				rate_float, _ := strconv.ParseFloat(rate.String(), 64)
				log.Println(step_1_symbol, step_2_symbol, step_3_symbol, "套利空间：", rate_float)
				if rate_float >= rate_setting {
					log.Println("======================================================")
					log.Println(step_1_symbol, "step_1_buy_price：", step_1_buy_price)
					log.Println(step_2_symbol, "step_2_sell_price：", step_2_sell_price)
					log.Println(step_3_symbol, "step_3_symbol_price：", step_3_symbol_sell_price)
					log.Println("=======================================================")
					isTrue := exchange.CreateOrder(step_1_buy, "BUY", step_1_symbol,step_1_symbol_minlots*lever*step_1_symbol_lotDenom)
					if isTrue == "true" {
						available_2,available_2_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step2Index].CoinName)

						available_2_v5:=exchange.GetLiuliuliu(available_2,available_2_denom,step_2_symbol_lotDenom)
						isTrue := exchange.CreateOrder(step_2_sell, "SELL", step_2_symbol, available_2_v5)
						if isTrue == "true" {
							available_3,available_3_denom:=exchange.GetBlance(price_data[schedulingIndexArg[i].Step3Index].BaseName)
							available_3_v5:=exchange.GetLiuliuliu(available_3,available_3_denom,step_3_symbol_lotDenom)
							isTrue := exchange.CreateOrder(step_3_symbol_sell, "BUY", step_3_symbol, available_3_v5)
							if isTrue == "true" {
								log.Println("套利成功1次。。。。。。。")
							}
						}
					}
				}

			}

		}
		time.Sleep(4*time.Millisecond)
		}
}

func RandInt64(min, max int64) int64 {
	if min >= max || min == 0 || max == 0 {
		return max
	}
	return rand.Int63n(max-min) + min
}